---
title: 0.30.0
description: Anchor - Release Notes 0.30.0
---

The long-awaited v0.30.0 release is finally here!

We'll go over the main changes, but if you'd like to see all notable changes,
check out the
[CHANGELOG](https://github.com/coral-xyz/anchor/blob/v0.30.0/CHANGELOG.md#0300---2024-04-15).

---

## How to upgrade

1. Update `avm`:

   ```sh
   cargo install --git https://github.com/coral-xyz/anchor --tag v0.30.0 avm --locked
   ```

2. Update `anchor-cli`:

   ```sh
   avm install latest
   ```

3. Update Anchor crate(s) to `0.30.0`. Optionally, run `cargo update` to update
   other dependencies to the latest compatible versions.

4. Update TS package(s) to `0.30.0`.

## Recommended Solana Version

While this release supports anything above `1.16`, the recommended Solana
version is `1.18.8`. You can upgrade Solana tools by running:

```
solana-install init 1.18.8
```

## IDL

The IDL type specification and generation has been rewritten. To keep the
release notes short, we won't go over the changes here, but see
[this](https://github.com/coral-xyz/anchor/pull/2824) if you'd like to learn
more.

### `idl-build` feature

`idl-build` feature is now required in your program's `Cargo.toml` definition in
order for the IDL generation to work.

Without this feature, `anchor build` outputs:

```
Error: `idl-build` feature is missing. To solve, add

[features]
idl-build = ["anchor-lang/idl-build"]

in `<PATH_TO_CARGO_TOML>`.
```

Note that all crates that you use to generate type definitions for the IDL need
to be specified in the list of `idl-build`, e.g. `anchor-spl/idl-build`,
`some-program/idl-build`...

## Lang

### Dependency free program declaration

Depending on other crates who used different versions of Anchor is not the best
experience, to say the least. To solve this problem, program clients can now be
generated from their IDL using the new `declare_program!` macro:

```rust
declare_program!(program_name);
```

`program_name` is based on the file name of the IDL in `idls` directory, e.g.
`idls/program_name.json` is required to exist in order for the above example to
work.

This works for both on-chain (CPI) and off-chain (RPC) usage, allowing program
interactions without creating a
[dependency hell](https://en.wikipedia.org/wiki/Dependency_hell). Check out
[this](https://github.com/coral-xyz/anchor/blob/v0.30.0/tests/declare-program/programs/declare-program/src/lib.rs)
example for on-chain CPI usage.

For more information, see the macro's
[documentation](https://docs.rs/anchor-lang/0.30.0/anchor_lang/macro.declare_program.html).

### Token extensions

#### Constraints

There are new account constraints for
[Token Extensions (Token 2022)](https://solana.com/solutions/token-extensions):

- `group_pointer`:
  - `authority`
  - `group_address`
- `group_member_pointer`:
  - `authority`
  - `member_address`
- `metadata_pointer`:
  - `authority`
  - `metadata_address`
- `close_authority`
  - `authority`
- `permanent_delegate`:
  - `delegate`
- `transfer_hook`:
  - `authority`
  - `program_id`

**Note:** Above values are concatinated with `::` (similar to other Anchor
constraints) and have `extensions` prefix e.g.
`extensions::group_pointer::authority = <EXPR>`.

These constraints can be used both with or without the `init` constraint.

[Here](https://github.com/coral-xyz/anchor/blob/v0.30.0/tests/spl/token-extensions/programs/token-extensions/src/instructions.rs)
is an example program that uses these constraints.

#### CPI wrappers

`anchor-spl` now includes CPI wrappers for Token Extensions which can be
accessed from `anchor_spl::token_2022_extensions`.

### `#[interface]` attribute

Transfer hooks can now be used with the new `#[interface]` macro. This argument
overrides the Anchor's default instruction discriminator to use the interface
instruction's discriminator.

Current supported values are:

- `spl_transfer_hook_interface::initialize_extra_account_meta_list`
- `spl_transfer_hook_interface::execute`

```rust
mod my_hook_program {
    #[interface(spl_transfer_hook_interface::initialize_extra_account_meta_list)]
    pub fn initialize(ctx: Context<Initialize>, metas: Vec<AnchorExtraAccountMeta>) -> Result<()> {
        /* ... */
    }

    #[interface(spl_transfer_hook_interface::execute)]
    pub fn execute(ctx: Context<Execute>, amount: u64) -> Result<()> {
        /* ... */
    }
}
```

### Optional bumps

When an optional account is not specified, instead of defaulting it to
`u8::MAX`, this release changes the optional bump type to be `Option<u8>` and
sets the bump field to `None`.

### Less heap allocations

[`BorshSerialize::try_to_vec`](https://github.com/near/borsh-rs/blob/79097e3c71ae469a101b4828457792bcf8be7f5f/borsh/src/ser/mod.rs#L47-L51)
implementation, which is used in events, CPI, and return data, heap allocates
[1024](https://github.com/near/borsh-rs/blob/79097e3c71ae469a101b4828457792bcf8be7f5f/borsh/src/ser/mod.rs#L19)
bytes each time it's used, even if your data is much smaller. In this release,
the default allocation is set to 256 bytes.

There is also a new method `InstructionData::write_to()` to write to an existing
allocation rather than creating a new allocation with `InstructionData::data()`.

## CLI

### Priority fees in CLI

IDL commands take in `--priority-fee` argument As it's getting harder and harder
to land transactions in mainnet-beta without using priority fees, this release
supports setting `--priority-fee` argument for the IDL commands. For example:

```
anchor idl erase-authority --program-id <PROGRAM_ID> --priority-fee 9000
```

When the `--priortiy-fee` argument is not specified, the median fee of the last
150 confirmed slots is used.

### `--no-idl` flag on builds

IDL generation requires building of the program, but this is unnecessary if your
program API doesn't change. In that case, you can use `--no-idl` flag to build
your program but skip the IDL generation:

```
anchor build --no-idl
```

### IDL buffer is closed after `idl upgrade`

After an IDL upgrade, the buffer account is now closed and the lamports are
returned back to the IDL authority.

### Pass deploy arguments to `solana-cli`

You can now pass arguments to `solana program deploy` from `anchor deploy`:

```
anchor deploy -- --final
```

### Verifiable deployments

Similar to verifiable builds, you can now deploy the verified build instead of
the default build:

```
anchor deploy --verifiable
```

### Accept package name as program name

`--program-name` (`-p`) argument of various commands also works with package
name of the program rather than lib name which is snake_case. For example:

```
anchor build -p my-program
```

### Deactivate test-validator features

You can now deactivate test-validator features from `Anchor.toml`:

```toml
[test.validator]
deactivate_feature = ["GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm", "zkiTNuzBKxrCLMKehzuQeKZyLtX2yvFcEKMML8nExU8"]
```

### Crate and package compatibility

Using non-matching versions of `anchor-cli`, `anchor-lang`, and
`@coral-xyz/anchor` can result in unexpected behavior. In this release, you'll
get a warning if any of them don't match.

### Explicit `overflow-checks` flag

[`overflow-checks`](https://doc.rust-lang.org/cargo/reference/profiles.html#overflow-checks)
flag is implicitly disabled by default. Anchor workspaces that are crated with
`anchor init` have this flag enabled, however, Anchor doesn't do any checks for
it after the initial workspace creation.

With this release, `overflow-checks` in the workspace `Cargo.toml` need to be
specified. Note that "specified" does not mean enabled, as you can also disable
it, but you need to be explicit in doing so.

### Wildcard pattern in `Anchor.toml`

`workspace.members` and `workspace.exclude` now supports simple wildcard
pattern:

```toml
[workspace]
members = ["programs/*"]
```

Note that the support is limited to this simple wildcard pattern, and more
complex globs are not currently supported.

### `cargo build-sbf` is now the default

Before this release, `anchor build` used `cargo build-bpf` to build programs,
however, because it is deprecated, `anchor build` now defaults to
`cargo build-sbf`.

To preserve the old behavior, you can use:

```
anchor build --arch bpf
```

### Run multiple commands in scripts

Scripts in `Anchor.toml` now supports running multiple commands:

```toml
[scripts]
test-all = "cargo test && yarn run ts-mocha tests/**/*.ts"
```

This script would run both `cargo` and `yarn` commands:

```
anchor run test-all
```

### Test only a specified program

A single program can be tested in a multi program workspace with the
`--program-name` (`-p`) argument:

```
anchor test --program-name example
```

This builds and tests only the specified program.

### Rust test template

A wild TypeScript test won't appear if you initialize your workspace with the
new Rust test template:

```
anchor init --test-template rust
```

## TypeScript

### Account resolution

Account resolution refers to the ability of clients to resolve accounts without
having to manually specify them when sending transactions.

There are too many changes to the account resolution logic in the TS library,
however, we can skip a good chunk of them since they're mostly internal.

One change that affects everyone is the change in the `accounts` method. Even
though the TS library had some support for account resolution, it had no
type-level support for it — all accounts were essentially typed as partial, and
there was no way to know which accounts were resolvable and which were not.

There are now 3 methods to specify accounts with the transaction builder:

- `accounts`: This method is now fully type-safe based on the resolution fields
  in the IDL, making it much easier to only specify the accounts that are
  actually needed.
- `accountsPartial`: This method keeps the old behavior and let's you specify
  all accounts including the resolvable ones.
- `accountsStrict`: If you don't want to use account resolution and specify all
  accounts manually (unchanged).

This change is likely to result in errors in your existing `.accounts()` calls.
To fix, either change `accounts` to `accountsPartial`, or remove all accounts
that can be resolved from the IDL. For example:

```diff
- await program.methods
-   .init()
-   .accounts({
-     pda: ...,
-     signer: ...,
-     systemProgram: ...,
-   })
-   .rpc();
+ await program.methods.init().rpc();
```

### Magic account names

Another change that affects most projects is the removal of "magic" account
names. The TS library used to autofill common program and sysvar accounts based
on their name, e.g. `systemProgram`, however, this is no longer necessary with
the introduction of the `address` field (in the IDL) which is used to resolve
all program and sysvars by default.

### Case conversion

The internals of the TS library are filled with case conversion logic before
making string comparison and this also forces other libraries who build on top
of Anchor to do the same.

Along with making the IDL have consistent casing, TS library also has consistent
casing (camelCase) in this release.

### No more Program ID

`programId` parameter of `Program` is removed since the new IDL requires to
store the program id in its `address` field:

```diff
- new Program(idl, programId);
+ new Program(idl);
```

### Optional provider options

`opts` parameter of `AnchorProvider` is now optional:

```diff
- new AnchorProvider(connection, wallet, {});
+ new AnchorProvider(connection, wallet);
```

### Type changes

There are too many type changes to list here, especially the types that are
related to the IDL. The new IDL types can be found
[here](https://github.com/coral-xyz/anchor/blob/v0.30.0/ts/packages/anchor/src/idl.ts).

---

See the full list of notable changes in the
[CHANGELOG](https://github.com/coral-xyz/anchor/blob/v0.30.0/CHANGELOG.md#0300---2024-04-15).
